package org.celery.modules.order.controller;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import io.swagger.annotations.Api;

import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.AllArgsConstructor;

import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;

import lombok.SneakyThrows;
import org.apache.commons.codec.Charsets;
import org.celery.modules.order.enums.OrderStatusEnum;
import org.celery.modules.order.enums.OrderStatusShipEnum;
import org.celery.modules.order.excel.OrderExcel;
import org.celery.modules.order.excel.OrderGoodsExcel;
import org.springblade.core.log.exception.ServiceException;
import org.springblade.core.mp.support.Condition;
import org.springblade.core.mp.support.Query;
import org.springblade.core.secure.BladeUser;
import org.springblade.core.secure.utils.SecureUtil;
import org.springblade.core.tool.api.R;
import org.springblade.core.tool.utils.Func;
import org.springblade.modules.system.entity.User;
import org.springblade.modules.system.service.IUserService;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.bind.annotation.RequestParam;
import com.baomidou.mybatisplus.core.metadata.IPage;
import org.celery.modules.order.entity.Order;
import org.celery.modules.order.vo.OrderVO;
import org.celery.modules.order.wrapper.OrderWrapper;
import org.celery.modules.order.service.IOrderService;
import org.springblade.core.boot.ctrl.BladeController;
import springfox.documentation.annotations.ApiIgnore;

import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 订单表 控制器
 *
 * @author Celery
 * @since 2022-04-04
 */
@RestController
@AllArgsConstructor
@RequestMapping("celery-order/order")
@Api(value = "订单表", tags = "订单表接口")
public class OrderController extends BladeController {

	private final IOrderService orderService;
	private final IUserService userService;

	/**
	 * 详情
	 */
	@GetMapping("/detail")
	@ApiOperationSupport(order = 1)
	@ApiOperation(value = "详情", notes = "传入order")
	public R<OrderVO> detail(Order order) {
		Order detail = orderService.getOne(Condition.getQueryWrapper(order));
		return R.data(OrderWrapper.build().entityVO(detail));
	}

	/**
	 * 分页 订单表
	 */
	@GetMapping("/list")
	@ApiOperationSupport(order = 2)
	@ApiOperation(value = "分页", notes = "传入order")
	public R<IPage<OrderVO>> list(Order order, Query query, BladeUser bladeUser) {
		QueryWrapper<Order> queryWrapper = Condition.getQueryWrapper(order);
		queryWrapper.lambda().orderByAsc(Order::getShipStatus).orderByDesc(Order::getCreateTime);
		if (Func.isNotEmpty(order.getReceiverName())) {
			queryWrapper.lambda().like(Order::getReceiverName, order.getReceiverName());
			order.setReceiverName(null);
		}
		if (Func.isNotEmpty(order.getReceiverPhone())) {
			queryWrapper.lambda().like(Order::getReceiverPhone, order.getReceiverPhone());
			order.setReceiverPhone(null);
		}

		if (!SecureUtil.isAdministrator()) {
			queryWrapper.lambda().eq(Order::getTenantId, bladeUser.getTenantId());

			List<User> allUnderUserList = userService.getUnderUserIdList(bladeUser);
			queryWrapper.lambda().in(
					Order::getFromUser,
					allUnderUserList.stream().map(User::getId).collect(Collectors.toList())
			);
		}

		IPage<Order> pages = orderService.page(Condition.getPage(query), queryWrapper);
		return R.data(OrderWrapper.build().pageVO(pages));
	}


	/**
	 * 自定义分页 订单表
	 */
	@GetMapping("/page")
	@ApiOperationSupport(order = 3)
	@ApiOperation(value = "分页", notes = "传入order")
	public R<IPage<OrderVO>> page(OrderVO order, Query query) {
		IPage<OrderVO> pages = orderService.selectOrderPage(Condition.getPage(query), order);
		return R.data(pages);
	}

	/**
	 * 新增 订单表
	 */
	@PostMapping("/save")
	@ApiOperationSupport(order = 4)
	@ApiOperation(value = "新增", notes = "传入order")
	public R save(@Valid @RequestBody Order order) {
		return R.status(orderService.save(order));
	}

	/**
	 * 修改 订单表
	 */
	@PostMapping("/update")
	@ApiOperationSupport(order = 5)
	@ApiOperation(value = "修改", notes = "传入order")
	public R update(@Valid @RequestBody Order order) {
		return R.status(orderService.updateById(order));
	}

	/**
	 * 新增或修改 订单表
	 */
	@PostMapping("/submit")
	@ApiOperationSupport(order = 6)
	@ApiOperation(value = "新增或修改", notes = "传入order")
	public R submit(@Valid @RequestBody Order order) {
		return R.status(orderService.saveOrUpdate(order));
	}

	
	/**
	 * 删除 订单表
	 */
	@PostMapping("/remove")
	@ApiOperationSupport(order = 7)
	@ApiOperation(value = "逻辑删除", notes = "传入ids")
	public R remove(@ApiParam(value = "主键集合", required = true) @RequestParam String ids) {
		return R.status(orderService.deleteLogic(Func.toLongList(ids)));
	}

	/**
	 * 老用户历史订单
	 */
	@GetMapping("/history-list")
	@ApiOperationSupport(order = 2)
	@ApiOperation(value = "分页", notes = "传入order")
	public R<IPage<OrderVO>> historyList(Order order, Query query, BladeUser bladeUser) {
		QueryWrapper<Order> queryWrapper = Condition.getQueryWrapper(order);
		queryWrapper.lambda().orderByAsc(Order::getShipStatus).orderByDesc(Order::getCreateTime);

		queryWrapper.lambda().eq(Order::getReceiverEmail, order.getReceiverEmail())
				.or().eq(Order::getFromIp, order.getFromIp())
				.or().eq(Order::getReceiverPhone, order.getReceiverPhone());
		order.setReceiverEmail(null);
		order.setReceiverPhone(null);
		order.setFromIp(null);

		if (!SecureUtil.isAdministrator()) {
			queryWrapper.lambda().eq(Order::getTenantId, bladeUser.getTenantId());

			List<User> allUnderUserList = userService.getUnderUserIdList(bladeUser);
			queryWrapper.lambda().in(
					Order::getFromUser,
					allUnderUserList.stream().map(User::getId).collect(Collectors.toList())
			);
		}

		IPage<Order> pages = orderService.page(Condition.getPage(query), queryWrapper);
		return R.data(OrderWrapper.build().pageVO(pages));
	}


	/**
	 * 导出订单
	 */
	@SneakyThrows
	@GetMapping("export-order")
	@ApiOperationSupport(order = 9)
	@ApiOperation(value = "导出订单")
	public void exportOrder(@ApiIgnore @RequestParam List<Long> orderIds, HttpServletResponse response) {
		QueryWrapper<Order> queryWrapper = new QueryWrapper<>();
		queryWrapper.lambda().in(Order::getId, orderIds);
		List<OrderExcel> list = orderService.exportOrder(queryWrapper);
		List<OrderGoodsExcel> orderExcelList = orderService.exportOrderGoods(queryWrapper);

		response.setContentType("application/vnd.ms-excel");
		response.setCharacterEncoding(Charsets.UTF_8.name());
		String fileName = URLEncoder.encode("配货订单", Charsets.UTF_8.name());
		response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx");
		ExcelWriter excelWriter = EasyExcel.write(response.getOutputStream()).build();

		WriteSheet sheet1 = EasyExcel.writerSheet(0, "sheet1")
				.head(OrderExcel.class)
				.build();
		excelWriter.write(list, sheet1);
		WriteSheet sheet2 = EasyExcel.writerSheet(1, "sheet2")
				.head(OrderGoodsExcel.class)
				.build();
		excelWriter.write(orderExcelList, sheet2);

		excelWriter.finish();
		response.flushBuffer();
	}

	/**
	 * 导出待配货订单
	 */
	@SneakyThrows
	@GetMapping("export-order-todo")
	@ApiOperationSupport(order = 10)
	@ApiOperation(value = "导出待配货订单")
	public void exportOrderTodo(BladeUser bladeUser, String tenantId, Long fromUser, HttpServletResponse response) {
		QueryWrapper<Order> queryWrapper = new QueryWrapper<>();

		if (!SecureUtil.isAdministrator()) {
			queryWrapper.lambda().eq(Order::getTenantId, bladeUser.getTenantId());
			List<Long> userIdList = userService.getUnderUserIdList(bladeUser).stream().map(User::getId).collect(Collectors.toList());
			queryWrapper.lambda().in(
					Order::getFromUser,
					userIdList
			);
		}
		if (Func.isNotEmpty(tenantId)) {
			queryWrapper.lambda().eq(Order::getTenantId, tenantId);
		}
		if (Func.isNotEmpty(fromUser)) {
			queryWrapper.lambda().eq(Order::getFromUser, fromUser);
		}
		queryWrapper.lambda().eq(Order::getStatus, OrderStatusEnum.NORMAL.getStatus());
		queryWrapper.lambda().eq(Order::getShipStatus, OrderStatusShipEnum.TO_BE_SHIP.getStatus());
		List<OrderExcel> list = orderService.exportOrder(queryWrapper);
		List<OrderGoodsExcel> orderExcelList = orderService.exportOrderGoods(queryWrapper);

		if (Func.isEmpty(list)) {
			throw new ServiceException("暂无待配货订单");
		}

		response.setContentType("application/vnd.ms-excel");
		response.setCharacterEncoding(Charsets.UTF_8.name());
		String fileName = URLEncoder.encode("待配货订单", Charsets.UTF_8.name());
		response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx");
		ExcelWriter excelWriter = EasyExcel.write(response.getOutputStream()).build();

		WriteSheet sheet1 = EasyExcel.writerSheet(0, "sheet1")
				.head(OrderExcel.class)
				.build();
		excelWriter.write(list, sheet1);
		WriteSheet sheet2 = EasyExcel.writerSheet(1, "sheet2")
				.head(OrderGoodsExcel.class)
				.build();
		excelWriter.write(orderExcelList, sheet2);

		excelWriter.finish();
		response.flushBuffer();
	}

	/**
	 * 修改订单状态
	 */
	@PostMapping("/change-status")
	@ApiOperationSupport(order = 11)
	@ApiOperation(value = "修改订单状态")
	public R changeStatus(String ids, Integer status) {
		List<Order> orderList = new ArrayList<>();
		for (Long id: Func.toLongList(",", ids)) {
			orderList.add(new Order() {{
				setId(id);
				setShipStatus(status);
			}});
		}
		return R.status(orderService.saveOrUpdateBatch(orderList));
	}

	/**
	 * 修改待配货订单状态
	 */
	@PostMapping("/change-status-todo")
	@ApiOperationSupport(order = 12)
	@ApiOperation(value = "修改待配货订单状态")
	public R changeStatus(Integer status, String tenantId, Long fromUser, BladeUser bladeUser) {
		QueryWrapper<Order> queryWrapper = new QueryWrapper<>();

		if (!SecureUtil.isAdministrator()) {
			queryWrapper.lambda().eq(Order::getTenantId, bladeUser.getTenantId());
			List<Long> userIdList = userService.getUnderUserIdList(bladeUser).stream().map(User::getId).collect(Collectors.toList());
			queryWrapper.lambda().in(
					Order::getFromUser,
					userIdList
			);
		}
		if (Func.isNotEmpty(tenantId)) {
			queryWrapper.lambda().eq(Order::getTenantId, tenantId);
		}
		if (Func.isNotEmpty(fromUser)) {
			queryWrapper.lambda().eq(Order::getFromUser, fromUser);
		}
		queryWrapper.lambda().eq(Order::getStatus, OrderStatusEnum.NORMAL.getStatus());
		queryWrapper.lambda().in(Order::getShipStatus, OrderStatusShipEnum.TO_BE_CONFIRM.getStatus(), OrderStatusShipEnum.TO_BE_SHIP.getStatus());
		List<Order> list = orderService.list(queryWrapper);

		if (Func.isEmpty(list)) {
			throw new ServiceException("暂无待配货订单");
		}

		for (Order order : list) {
			order.setShipStatus(status);
		}
		return R.status(orderService.saveOrUpdateBatch(list));
	}

}
